//
//  Element3D.hpp
//  C3W_Demo_By_Fan
//
//  Created by 范静涛 on 2024/7/23.
//

//------------------------------------------------------------------------------
//【文件名】Element3D.hpp
//【功能模块和目的】三维基元类(若干非重复三维点构成)声明
//【开发者及日期】范静涛 2024/7/23
//【更改记录】
//------------------------------------------------------------------------------

#ifndef Element3D_hpp
#define Element3D_hpp


//size_t所属头文件
#include <cstddef>
//std::vector所属头文件
#include <vector>
//Point3D类所属头文件
#include "Point3D.hpp"
//Point3DSet类所属头文件
#include "Point3DSet.hpp"

//------------------------------------------------------------------------------
//【类名】Element3D
//【功能】三维基元类(若干非重复三维点构成)
//【接口说明】
//    默认构造函数
//    带参数构造函数
//    拷贝构造函数
//    赋值运算符overload
//    虚析构函数（可能做基类）
//    添加非重复点到基元(从概念出发，因存在的对象行为)
//    修改基元中已存在点(从概念出发，因存在的对象行为)
//    删除基元中已存在点(从概念出发，因存在的对象行为)
//    清空基元(从概念出发，因存在的对象行为)
//    流插入运算符overload(从概念出发，因存在的对象行为)
//    判断基元相等(从概念出发，因存在的对象行为)
//    判断基元不等(从概念出发，因存在的对象行为)
//    求面积接口，纯虚函数(从概念出发，因存在的对象行为)
//    求长度接口，纯虚函数(从概念出发，因存在的对象行为)
//    派生类接口：按规则添加点(从概念出发，因存在的对象行为)
//    派生类接口：按规则修改点(从概念出发，因存在的对象行为)
//    派生类接口：按规则删除点(从概念出发，因存在的对象行为)
//    派生类接口：按规则清空基元(从概念出发，因存在的对象行为)
//    三维点集Points(从概念出发，应存在的类属性)
//    三维点数量PointCount(从概念出发，应存在的对象属性)
//【开发者及日期】 范静涛 2024/7/23
//【更改记录】
//------------------------------------------------------------------------------
class Element3D{
public:
    //--------------------------------------------------------------------------
    //必要的构造、析构、赋值行为
    //--------------------------------------------------------------------------
    //默认构造函数
    Element3D(size_t MaxPointCount = Point3DSet::MAX_COUNT);
    //带参构造函数
    Element3D(const std::vector<Point3D>& Source);
    //拷贝构造函数
    Element3D(const Element3D& Source);
    //赋值运算符overload
    Element3D& operator=(const Element3D& Source);
    //虚析构函数（可能做基类），无动态构造成员，默认实现
    virtual ~Element3D() = default;
    //--------------------------------------------------------------------------
    //非静态Setter成员函数
    //--------------------------------------------------------------------------
    //添加一个不重复三维点
    void AppendPoint(const Point3D& APoint);
    //修改一个已存在三维点坐标为非重复三维点
    void ModifyPoint(const Point3D& From, const Point3D& To);
    //删除一个已存在三维点
    void RemovePoint(const Point3D& APoint);
    //清空三维点
    void Clear();
    //--------------------------------------------------------------------------
    //非静态Getter成员函数：需检查所有Getter是否有后置const
    //--------------------------------------------------------------------------
    //流插入运算符friend overload
    friend std::ostream& operator<<(std::ostream& Stream, 
        const Element3D& AnElement);
    //判断基元相等
    bool operator==(const Element3D& AnElement) const;
    //判断基元不等
    bool operator!=(const Element3D& AnElement) const;
    //求面积接口
    virtual double Area() const = 0;
    //求长度接口
    virtual double Length() const = 0;
protected:
    //--------------------------------------------------------------------------
    //受保护 非静态Setter成员函数
    //--------------------------------------------------------------------------
    //根据规则添加三维点，派生类可overload
    virtual void AppendPointByRule(const Point3D& APoint);
    //根据规则修改三维点，派生类可overload
    virtual void ModifyPointByRule(const Point3D& From, const Point3D& To);
    //根据规则删除三维点，派生类可overload
    virtual void RemovePointByRule(const Point3D& APoint);
    //根据规则清空三维点，派生类可overload
    virtual void ClearByRule();
private:
    //--------------------------------------------------------------------------
    //私有 非静态数据成员
    //--------------------------------------------------------------------------
    //三维点实际存储
    Point3DSet m_Points;
public:
    //--------------------------------------------------------------------------
    //非静态Getter成员
    //--------------------------------------------------------------------------
    //三维点实际存储
    const Point3DSet& Points{m_Points};
    //三维点数量
    const size_t& PointCount{m_Points.Count};
};

#endif /* Element3D_hpp */
